package com.hopedove.tempdemo.utils

import android.content.Context
import android.graphics.Color
import android.util.Size
import android.view.Gravity
import android.view.View
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout


/***
 *  根据业务需求
 *  给 ConstraintLayout 按照行列添加子 View
 *
 *  @param bottomIndicate 如果为 true ，则在最下面额外加入一行显示索引
 */
fun addArrangement(
    rowCount: Int,
    columnCount: Int,
    container: ConstraintLayout,
    viewSize: Size = Size(50, 50),
    bottomIndicate: Boolean = false,
    bottomOrderInc: Boolean = true,
    rightIndicate: Boolean = false,
    rightOrderInc: Boolean = true,
    newView: Context.() -> View = { TextView(this) }
): Map<String, Int> {
    val idsMap = getIdsMap(rowCount, columnCount)
    val context = container.context
    val (width, height) = viewSize.let { Pair(it.width, it.height) }

    var preRowView: View? = null
    for (row in 1..rowCount) {
        var prevChild: View? = null
        for (col in 1..columnCount) {
            val childView = context.newView().apply { id = idsMap["${row}x${col}"]!! }
            val layoutParams = ConstraintLayout.LayoutParams(width, height).apply {
                topMargin = 1
                leftMargin = 1
                rightMargin = 1
                bottomMargin = 1
            }

            childView.setBackgroundColor(Color.WHITE)

            if (prevChild == null) {
                layoutParams.leftToLeft = ConstraintLayout.LayoutParams.PARENT_ID
            } else {
                layoutParams.leftToRight = prevChild.id
                val preLp = prevChild.layoutParams as ConstraintLayout.LayoutParams
                preLp.rightToLeft = childView.id
            }

            if (preRowView != null) {
                layoutParams.topToBottom = preRowView.id
            }
            if (col == columnCount) {
                layoutParams.rightToRight = ConstraintLayout.LayoutParams.PARENT_ID
                preRowView = childView
            }
            prevChild = childView
            container.addView(childView, layoutParams)
        }
    }


    addIndicate(
        rowCount,
        columnCount,
        container,
        idsMap.toMutableMap(),
        viewSize,
        bottomIndicate,
        bottomOrderInc,
        rightIndicate,
        rightOrderInc
    )

    container.setPadding(1, 1, 1, 1)
    return idsMap
}

/**
 *  根据行号和列号生成 view id
 */
private fun getIdsMap(rowCount: Int, columnCount: Int): Map<String, Int> {
    return mutableMapOf<String, Int>().apply {
        for (row in 1..rowCount) {
            for (col in 1..columnCount) {
                this["${row}x${col}"] = View.generateViewId()
            }
        }
    }
}

private fun addIndicate(
    rowCount: Int,
    columnCount: Int,
    container: ConstraintLayout,
    idsMap: MutableMap<String, Int>,
    viewSize: Size,
    bottom: Boolean = false,
    bottomOderInc: Boolean = true,
    right: Boolean = false,
    rightOrderInc: Boolean = true
) {
    if (bottom.not() && right.not()) return

    if (bottom) {
        var prevChild: View? = null
        val aboveView = container.findViewById<View>(idsMap["${rowCount}x${columnCount}"] ?: return)
        val context = aboveView?.context ?: return
        for (col in 1..columnCount) {
            val textView = TextView(context).apply {
                id = View.generateViewId()
                idsMap["${rowCount + 1}x$col"] = id
            }
            val layoutParams = newConstraintLayoutParam(viewSize, 1)
            val value = if (bottomOderInc) "$col" else "${columnCount + 1 - col}"
            textView.text = value
            textView.gravity = Gravity.CENTER
            textView.setBackgroundColor(Color.WHITE)

            if (prevChild == null) {
                layoutParams.leftToLeft = ConstraintLayout.LayoutParams.PARENT_ID
            } else {
                layoutParams.leftToRight = prevChild.id
                val preLp = prevChild.layoutParams as ConstraintLayout.LayoutParams
                preLp.rightToLeft = textView.id
            }

            layoutParams.topToBottom = aboveView.id

            if (col == columnCount) {
                layoutParams.rightToRight = ConstraintLayout.LayoutParams.PARENT_ID
            }
            prevChild = textView
            container.addView(textView, layoutParams)
        }
    }

    if (right) {
        var prevChild: View? = null

        for (row in 0 until rowCount) {
            val leftView =
                container.findViewById<View>(idsMap["${row + 1}x${columnCount}"] ?: return)
            val context = leftView?.context ?: return

            val textView = TextView(context).apply {
                id = View.generateViewId()
                idsMap["${row + 1}x${columnCount + 1}"] = id
            }

            val layoutParams = newConstraintLayoutParam(viewSize, 1)
            val value = if (rightOrderInc) "${row + 1}" else "${rowCount - row}"
            textView.text = value
            textView.gravity = Gravity.CENTER
            textView.setBackgroundColor(Color.WHITE)

            layoutParams.leftToRight = leftView.id
            layoutParams.rightToRight = ConstraintLayout.LayoutParams.PARENT_ID
            val leftLayoutParam = leftView.layoutParams as ConstraintLayout.LayoutParams
            leftLayoutParam.rightToLeft = textView.id

            if (prevChild == null) {
                layoutParams.topToTop = ConstraintLayout.LayoutParams.PARENT_ID
            } else {
                layoutParams.topToBottom = prevChild.id
            }
            prevChild = textView
            container.addView(textView, layoutParams)
        }
    }

    if (right && bottom) {
        val leftView =
            container.findViewById<View>(idsMap["${rowCount + 1}x${columnCount}"] ?: return)
        val context = leftView?.context ?: return
        val textView = TextView(context).apply { id = View.generateViewId() }
        val layoutParams = newConstraintLayoutParam(viewSize, 1)
        textView.text = "0"
        textView.gravity = Gravity.CENTER
        textView.setBackgroundColor(Color.WHITE)

        layoutParams.rightToRight = ConstraintLayout.LayoutParams.PARENT_ID
        layoutParams.leftToRight = leftView.id
        val leftLayoutParam = leftView.layoutParams as ConstraintLayout.LayoutParams
        leftLayoutParam.rightToLeft = textView.id
        layoutParams.topToTop = leftView.id
        container.addView(textView, layoutParams)
    }
}


private fun newConstraintLayoutParam(size: Size, margin: Int): ConstraintLayout.LayoutParams {
    return ConstraintLayout.LayoutParams(size.width, size.height).apply {
        topMargin = margin
        leftMargin = margin
        rightMargin = margin
        bottomMargin = margin
    }
}